# -*- coding:UTF-8 -*-
"""
@author: dyy
@contact: douyaoyuan@126.com
@time: 2023/8/8 14:18
@file: 效果测试.py
@desc: 测试 DebugInfo 模块的相关功能
"""

# region 引入 调试模块
import os
from datetime import datetime, timedelta
import time
from src.DebugInfo.DebugInfo import *


# from DebugInfo import *

# endregion


# 定义一个入参类,用于解析和管理命令行入参参数
class 入参类(入参基类):
    def __init__(self):
        super().__init__()

        self._添加参数('cless', int, '这个参数是class的替身', 1)
        self._添加参数('班级', int, '请输入班级信息', 2)
        self._添加参数('年级', [1, 2, 3, 4], '请输入年级信息', 4)
        self._添加参数('firstName', ['li', 'zhang', 'zhao'], '请输入姓氏', 'zhang')
        self._添加参数('列表参数', (list, 5), '这个参数可以接收5个值', 1)
        self._添加参数('show', None, '展示参数列表', False)

    # region 访问器
    @property
    def jsonCfg(self) -> str:
        if 'jsonCfg' in self._参数字典:
            return self._参数字典['jsonCfg'].值
        else:
            return ''

    @jsonCfg.setter
    def jsonCfg(self, 值: str):
        if 'jsonCfg' in self._参数字典:
            self._参数字典['jsonCfg'].值 = str(值)

    @property
    def cless(self) -> int:
        if 'cless' in self._参数字典:
            return self._参数字典['cless'].值
        else:
            return 0

    @cless.setter
    def cless(self, 值: int):
        if 'cless' in self._参数字典:
            if type(值) in [int, float]:
                self._参数字典['cless'].值 = int(值)

    @property
    def 班级(self) -> int:
        if '班级' in self._参数字典:
            return self._参数字典['班级'].值
        else:
            return 0

    @班级.setter
    def 班级(self, 值: int):
        if '班级' in self._参数字典:
            if type(值) in [int, float]:
                self._参数字典['班级'].值 = int(值)

    @property
    def firstName(self) -> str:
        if 'firstName' in self._参数字典:
            return self._参数字典['firstName'].值
        else:
            return ''

    @firstName.setter
    def firstName(self, 值: str):
        if 'firstName' in self._参数字典:
            self._参数字典['firstName'].值 = str(值)

    @property
    def show(self) -> bool or None:
        if 'show' in self._参数字典:
            return self._参数字典['show'].值
        else:
            return None

    @show.setter
    def show(self, 值: bool):
        if 'show' in self._参数字典:
            if isinstance(值, bool):
                self._参数字典['show'].值 = 值
            else:
                self._参数字典['show'].值 = None
    # endregion


# 一个方法,用来测试秒表装饰器效果
@秒表
def 秒表测试方法(填充次数: int = 500, 休眠时间: int = 1, 画板: 打印模板 = None):
    """
    这个方法用于演示如何使用 秒表 装饰器
    :param 填充次数:
    :param 休眠时间:
    :param 画板:
    :return:
    """
    画板 = 画板 if isinstance(画板, 打印模板) else 打印模板()
    画板.执行位置(秒表测试方法)

    画板.准备表格()

    填充次数 = max(1, 填充次数)
    画板.消息(f'填充表格 {填充次数} 次')
    for 序号 in range(填充次数):
        画板.添加一行(序号, '秒表演示')

    休眠时间 = max(0.001, 休眠时间)
    画板.消息(f'休眠 {休眠时间}s')
    time.sleep(休眠时间)


if __name__ == '__main__':
    # 对象实例化时,可以指定调试模式,也可以指定其它参数
    画板 = 打印模板(True)

    # 如果调试模式打开, 这里可以打印执行位置消息
    画板.执行位置(__file__ + '[位置提示只有在调试模式下会显示]')

    # 可以关闭调试模式
    画板.调试状态 = False
    # 关闭调试模式后,执行位置信息不再打印
    画板.执行位置(os.path.basename(__file__) + '[这个提示不应该被显示]')

    # 调试信息只有在调试状态才会打印输出
    画板.关闭调试()
    画板.调试消息('这是一个调试状态才会输出的消息, 这是1号消息')
    画板.打开调试()
    画板.调试消息('这是一个调试状态才会输出的消息, 这是2号消息, 你应该看不到1号消息的')

    # 可以进行缩进处理, 默认缩进一个空格符
    画板.消息('这是缩进前')
    画板.缩进()
    画板.消息('这是缩进后')
    # 你也可以指定缩进的字符,例如可以指定缩进两个空格
    画板.缩进('  ')
    画板.消息('注意,这一行相对上一行,缩进了两个空格')

    # 注意,缩进功能没有提供回退方法,推荐的方法是如果你需要临时缩进,你可以通过创建副本的方法来进行,对副本的操作不会影响原对象
    小画板: 打印模板 = 画板.副本.缩进()
    小画板.消息('这是新对象的打印,应该有一个缩进效果')
    画板.消息('这还是原对象的打印')

    # 你可以级联进行多个操作,例如 创建副本, 缩进, 打开调试
    宝宝: 打印模板 = 画板.副本.关闭调试().设置打印头('@')
    宝宝.消息('这是一个卵宝宝,请注意打印头符号')

    # 你可以打印一个错误消息,错误消息将标记为红色背景
    画板.提示错误('天啊,这里有一个致命错误[效果演示]')
    画板.调试错误(f'这个错误,只有在调试状态下才会显示,当前调试状态为:{画板.正在调试}')

    # 可以生成并打印一个分隔线
    画板.分隔线.符号('~ ').提示内容('这是一个黄色背景的分隔线').修饰(黄底).总长度(50).展示()
    画板.分隔线.符号('* ').提示内容('这是一个黄色字体的分隔线').修饰(黄字).总长度(60).展示()
    画板.分隔线.符号('* ').提示内容('这是一个黄色字体提示右对齐的分隔线').修饰(黄字).总长度(60).文本对齐('r').展示()
    画板.分隔线.总长度(5000, 适应窗口=True).提示内容('这个分隔线要求总长度5000,但同时要求适应终端').展示()
    画板.消息('下面是一个不加修饰的分隔线')
    画板.分隔线.展示()

    # 可以很方便的整理并打印一个表格
    画板.准备表格()  # 每次使用表格功能前,你需要手动准备一下表格
    画板.添加一行('列1', '|', '列2', '列3')  # 你可以把第一行的内容视做表头
    画板.添加一行('行1', '|', '天下', '太平')
    画板.添加一行('行2', '|', '和', '谐', '社', '会')
    画板.添加一行('', '|', '', '', '这一行前面的列没有内容', '这一列没有表头哈')

    # 你可以添加一行只有在调试模式才显示的内容
    画板.添加一调试行('行5', '|', '这一行只有调试状态下才显示')

    # 也可以通过list添加一行
    画板.添加一行(['行6', '', '', '行6列4'])

    # 也可以添加多行
    画板.添加多行([['行7', '行7列2'], ['行8', '', '行8列3']])
    画板.展示表格(填充字符=绿字('-'))

    画板.分隔线.提示内容('这是一个绿色的分隔线').修饰(绿字).展示()

    # 你可以在表格,或者其它需要的地方,使用颜色修饰你的字符
    画板.准备表格()
    画板.打印空行()
    画板.添加一行('彩字效果', '编码展示')
    彩字 = 蓝字('蓝字')
    画板.添加一行(彩字, 彩字.encode())
    彩字 = 红底(彩字 + '红底')
    画板.添加一行(彩字, 彩字.encode())
    彩字 = 黄底(彩字 + '黄底')
    画板.添加一行(彩字, 彩字.encode())
    彩字 = 绿字(彩字 + '绿字')
    画板.添加一行(彩字, 彩字.encode())
    画板.展示表格()

    画板.准备表格()
    画板.添加空行()
    画板.添加分隔行(提示文本='语义日期演示', 修饰方法=红字)
    画板.添加一行('日期', '日期语义')
    画板.添加一行(datetime.now().date() + timedelta(days=-365 * 5),
                  语义日期模板(datetime.now() + timedelta(days=-365 * 5)))
    画板.添加一行(datetime.now().date() + timedelta(days=-365), 语义日期模板(datetime.now() + timedelta(days=-365)))
    画板.添加一行(datetime.now().date() + timedelta(days=-180), 语义日期模板(datetime.now() + timedelta(days=-180)))
    画板.添加一行(datetime.now().date() + timedelta(days=-40), 语义日期模板(datetime.now() + timedelta(days=-40)))
    画板.添加一行(datetime.now().date() + timedelta(days=-20), 语义日期模板(datetime.now() + timedelta(days=-20)))
    画板.添加一行(datetime.now().date() + timedelta(days=-8), 语义日期模板(datetime.now() + timedelta(days=-8)))
    画板.添加一行(datetime.now().date() + timedelta(days=-2), 语义日期模板(datetime.now() + timedelta(days=-2)))
    画板.添加一行(datetime.now().date() + timedelta(days=-1), 语义日期模板(datetime.now() + timedelta(days=-1)))
    画板.添加一行(datetime.now().date() + timedelta(days=-0), 语义日期模板(datetime.now() + timedelta(days=-0)))
    画板.添加一行(datetime.now().date() + timedelta(days=1), 语义日期模板(datetime.now() + timedelta(days=1)))
    画板.添加一行(datetime.now().date() + timedelta(days=2), 语义日期模板(datetime.now() + timedelta(days=2)))
    画板.添加一行(datetime.now().date() + timedelta(days=3), 语义日期模板(datetime.now() + timedelta(days=3)))
    画板.添加一行(datetime.now().date() + timedelta(days=9), 语义日期模板(datetime.now() + timedelta(days=9)))
    画板.添加一行(datetime.now().date() + timedelta(days=18), 语义日期模板(datetime.now() + timedelta(days=18)))
    画板.添加一行(datetime.now().date() + timedelta(days=40), 语义日期模板(datetime.now() + timedelta(days=40)))
    画板.添加一行(datetime.now().date() + timedelta(days=180), 语义日期模板(datetime.now() + timedelta(days=180)))
    画板.添加一行(datetime.now().date() + timedelta(days=365), 语义日期模板(datetime.now() + timedelta(days=365)))
    画板.添加一行(datetime.now().date() + timedelta(days=365 * 4),
                  语义日期模板(datetime.now() + timedelta(days=365 * 4)))
    画板.展示表格()

    # 打印乘法表
    画板.准备表格()
    画板.添加多行([[f'{被乘数}*{乘数} = {被乘数 * 乘数}' for 被乘数 in range(1, 乘数 + 1)] for 乘数 in range(1, 10)])
    画板.打印空行()
    画板.分隔线.提示内容('展示乘法表').总长度(画板.表格宽度()).修饰(红字).展示()
    画板.展示表格()

    画板.打印空行()
    画板.分隔线.提示内容('左右颠倒表格').总长度(画板.表格宽度()).修饰(红字).展示()
    画板.副本.左右颠倒表格().展示表格()

    画板.打印空行()
    画板.分隔线.提示内容('上下颠倒乘法表').总长度(画板.表格宽度()).修饰(红字).展示()
    画板.副本.上下颠倒表格().展示表格()

    画板.打印空行()
    画板.分隔线.提示内容('对角线颠倒乘法表').总长度(画板.表格宽度()).修饰(红字).展示()
    画板.副本.上下颠倒表格().左右颠倒表格().展示表格()

    画板.准备表格()
    画板.添加空行()
    画板.添加分隔行(提示文本='表格对齐效果演示', 修饰方法=绿字)
    画板.设置列对齐(对齐控制串='左c右')
    画板.添加一行('左对齐', '居中对齐', '右对齐').修饰行(青字)
    画板.添加一行('左对齐一', '居中', '12', '应')
    画板.添加一行('左对齐一二', '居中', '123', '该是')
    画板.添加一行('左对齐一二三', '居--中', '1234', '右对齐的')
    画板.添加空行().展示表格()
    画板.左右颠倒表格().展示表格()

    秒表测试方法(1, 0, 画板.副本)

    画板.打印空行(2)
    画板.分隔线.提示内容('特殊符号可能会导致字长显示宽度计算错误,下面的分隔线会比较短').总长度(70).展示()
    画板.分隔线.提示内容('我的提示内容里有 ⭐  ⭐').总长度(70).修饰(黄字).展示()

    画板.特殊字符宽度字典 = {'⭐': 1}
    画板.分隔线.提示内容('明确指定符号⭐ 的宽度为1,这条分隔线不会短了').总长度(70).展示()
    画板.分隔线.提示内容('我的提示内容里有 ⭐  ⭐').总长度(70).修饰(黄字).展示()

    # 以下内容用于演示关于表格的分隔行, 以及修改指定行的用法
    画板.准备表格()
    # 向表格中添加内容
    画板.添加一行('事项类型', '内容', '', '百度翻译网站译文(作为参考)', '备注').修饰行(青字)
    画板.添加一行('待翻译内容', '主打一个反骨仔', '->', 'Focus on a villain')
    画板.添加一行('向AI提问', '主打一个反骨仔，翻译成英文', '', '', '向不同的模型提问, 各回答如下')

    # 这个行号所记录的行, 将来需要进行修改
    占位行号 = 画板.添加一行('').行号

    # 继续添加下半个表格的内容
    画板.添加一行('gpt-3.5-turbo', 'The Rebel Kid', '->', '叛逆小子')
    画板.添加一行('国内某一大模型', 'We mainly play a traitor', '->', '我们主要扮演叛徒')
    画板.添加一行('国内另一大模型', 'Maintain a rebellious person', '->', '保持一个叛逆的人')

    # 这一行是一个分隔行
    画板.添加分隔行(修饰方法=蓝字, 适应窗口=True)

    # 继续表格内容的添加
    画板.添加一行('', '', '', '', '继续添加表格内容...')

    # 修改占位行
    画板.修改指定行(占位行号, ['-' * 宽度 for 宽度 in 画板.表格列宽]).修饰行(绿字)

    # 表格内容 rdy， 展示你的表格吧；添加空行可以使下文的打印与当前的表格内容隔开，避免混乱
    画板.添加空行(1).展示表格()

    入参 = 入参类()
    入参.jsonCfg = r"c:\Users\yaoyuan.dou\Documents\myDocs\cfg.json"
    入参.解析Json(画板=画板.副本.缩进())
    入参.解析入参(画板=画板.副本.缩进())
    入参.展示(画板=画板.副本.缩进())

    画板.打印空行()
    画板.消息(f'终端宽度是: {窗口宽度()}')
    画板.消息(f'终端高度是: {窗口高度()}')

    交互端: 交互接口类 = 交互接口类()

    反馈 = 交互端.发起文本交互(输入提示='请输入一个文本: ', 画板=画板.副本)
    画板.消息(f'您输入的是:{反馈}')

    交互端.输入提示修饰方法 = 红字
    确认结果 = 交互端.发起文本交互(输入提示='你是否确认继续(y:继续; n: 返回): ', 限定范围='yYnN', 画板=画板.副本)
    if 确认结果 in 'yY':
        画板.消息(绿字('你确认了操作'))
    elif 确认结果 in 'nN':
        画板.消息(红字('您拒绝了操作'))
    else:
        画板.提示错误(f'程序出错了, 获得了一个非预期的反馈: {确认结果}')

    交互端.复位选项()
    交互端.添加选项(选项='自行车')
    交互端.添加选项(选项='电瓶车', 备注='推荐上下班场景下使用')
    交互端.添加选项(代号='c', 选项='小汽车')
    交互端.添加选项(选项='-')
    交互端.添加选项(代号='t', 选项='大卡车', 修饰方法=白底黄字)
    交互端.添加选项(选项='-')
    交互端.添加选项(代号='t', 选项='火车')
    用户选择 = 交互端.发起选项交互(输入提示='请选择一个你中意的交通工具:', 画板=画板.副本)
    画板.消息(f'您选择的交通工具是: {用户选择.选项[0]}')

    用户选择 = 交互端.发起选项交互(多选=True, 输入提示='请选择一个你中意的交通工具:', 画板=画板.副本)
    画板.消息(f'您选择的交通工具是: {用户选择.选项}')

    用户输入 = 交互接口类.发起文本交互(输入提示='请输入一个数字', 限定范围=str.isdigit, 画板=画板.副本)
    画板.消息(f'您的输入是: {用户输入}')

    everything搜索 = 搜索接口类(everything服务端口=22)

    用户选择 = 交互端.指定选择路径(输入提示='请指定路径,或者指定路径关键字:(0:反回):',
                                   搜索接口=everything搜索,
                                   画板=画板.副本)
    画板.准备表格()
    画板.添加分隔行()
    画板.添加一行('以下为您指定的路径:')
    画板.添加一行(用户选择)
    画板.展示表格()

    用户选择 = 交互端.选择文档(多选=True, 输入提示='请选择您要处理的文档:(0:反回):',
                               搜索接口=everything搜索,
                               画板=画板.副本)
    画板.准备表格()
    画板.添加分隔行()
    画板.添加一行('以下为您指定的文档:')
    画板.添加多行(用户选择, 拆分列数=1)
    画板.展示表格()
